package learnjdk.completablefuture;

import javax.lang.model.type.NullType;
import java.time.Clock;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * Created by alex on 2017/7/16.
 */
public class Main {

    private static final Map<String, Double> PRICE_MAP = new HashMap<>();
    private static final String[] KEY_ARRAY = {"a", "b", "c", "d", "e"};

    static {
        PRICE_MAP.put("a", 1.1D);
        PRICE_MAP.put("b", 2.3D);
        PRICE_MAP.put("c", 0.1D);
        PRICE_MAP.put("d", 3.21D);
        PRICE_MAP.put("e", 4.58D);
    }

    public static void main(String[] args) {
        long t0 = System.currentTimeMillis();
        parallelStream();

//        cf();
        System.out.println("Cost:" + (System.currentTimeMillis() - t0));
    }

    private static void measure(Function<?, Void> fun) {
        Clock clock = Clock.systemUTC();
        long t0 = clock.millis();
        fun.apply(null);
        System.out.println("cost:" + (clock.millis() - t0));
    }

    private static void cf() {
        List<CompletableFuture<Double>> pricesFuture = Arrays.stream(KEY_ARRAY)
                .map(key -> CompletableFuture.supplyAsync(() -> getPrice(key)))
                .collect(Collectors.toList());

        List<Double> prices = pricesFuture.stream()
                .map(f -> f.thenApply(p -> p * 0.1D))
                .map(CompletableFuture::join)
                .collect(Collectors.toList());
        System.out.println(prices.size());
    }

    // 普通并行流
    private static void parallelStream() {
        List<Double> prices = Arrays.stream(KEY_ARRAY).parallel()
                .map(Main::getPrice)
                .map(p -> p * 0.01F)
                .collect(Collectors.toList());
        System.out.println(prices.size());
    }

    private static double getPrice(String key) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            return PRICE_MAP.get(key);
        }
    }

}
